TOOL.Category   = "Conna's Tools"
TOOL.Name       = "#Position Switcher Tool"
TOOL.Command    = nil
TOOL.ConfigName = ""

// Settings

TOOL.Sel        = {}

TOOL.Sel[1]     = nil
TOOL.Sel[2]     = nil

// ConVars

TOOL.ClientConVar["Key"] = "5"
TOOL.ClientConVar["Ghost"] = "1"

// Client

if (CLIENT) then
	language.Add("Tool_positionswitcher_name", "Position Switcher Tool")
	language.Add("Tool_positionswitcher_desc", "Switch an entity between two positions")
	language.Add("Tool_positionswitcher_0", "Create two entities the same model and select them both with this tool")

	language.Add("Undone_positionswitcher", "Undone Position Switcher")
end

// Message

function TOOL:Message(Text)
	if SERVER then
		self:GetOwner():SendLua("GAMEMODE:AddNotify('"..Text.."', NOTIFY_GENERIC, 10)")
		self:GetOwner():SendLua("surface.PlaySound('ambient/water/drip"..math.random(1, 4)..".wav')")
	end
end

// Left click

function TOOL:LeftClick(Trace)
	if Trace.Entity then
		if !Trace.Entity:IsValid() or Trace.Entity:IsPlayer() or Trace.HitWorld or Trace.Entity:IsNPC() then
			return false
		end
	end
	
	if(CLIENT) then
		return true
	end

	if(!SERVER) then return false end
	
	if (Trace.Entity.PositionSwitcher) then
		self:Message("This entity is already part of a Position Switcher!")
		
		return false
	end
	
	if not self.Sel[1] then
		self.Sel[1] = Trace.Entity
		
		self:Message("First entity has been selected!")
		
		return true
	end
	
	if not (self.Sel[2]) then
		if (self.Sel[1]:IsValid()) then
			self.Sel[2] = Trace.Entity
			
			local Key = self:GetClientNumber("Key")
			
			Trace.Entity.PositionSwitcher = {}
			
			Trace.Entity.PositionSwitcher.Current = 2
			
			Trace.Entity.PositionSwitcher.FirstPosition = self.Sel[1]:GetPos()
			Trace.Entity.PositionSwitcher.SecondPosition = self.Sel[2]:GetPos()
			
			Trace.Entity.PositionSwitcher.FirstAngle = self.Sel[1]:GetAngles()
			Trace.Entity.PositionSwitcher.SecondAngle = self.Sel[2]:GetAngles()
			
			if (Wire_CreateOutputs) then
				Trace.Entity.Outputs = Wire_CreateOutputs(Trace.Entity, {"Position"})
			end
			
			if (Wire_TriggerOutput) then
				Wire_TriggerOutput(Trace.Entity, "Position", 2)
			end
			
			local Ghost = self:GetClientNumber("Ghost")
			
			local Table = {}
			
			if Ghost == 1 then
				for I = 1, 2 do
					Table[I] = ents.Create(self.Sel[I]:GetClass())
					Table[I]:SetPos(self.Sel[I]:GetPos())
					Table[I]:SetAngles(self.Sel[I]:GetAngles())
					Table[I]:SetModel(self.Sel[I]:GetModel())
					Table[I]:SetMoveType(MOVETYPE_NONE)
					Table[I]:SetNotSolid(true)
					Table[I]:PhysicsInit(SOLID_VPHYSICS)
					Table[I]:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
					Table[I]:DrawShadow(false)
					Table[I]:SetRenderMode(3)
					Table[I]:SetColor(255, 255, 255, 100)
					Table[I]:Spawn()
					
					local Phys = Table[I]:GetPhysicsObject()
					
					if Phys then
						Phys:EnableMotion(false)
					end
					
					Table[I].PositionSwitcher = {}
				end
				
				local Phys = Trace.Entity:GetPhysicsObject()
				
				if Phys then
					Phys:EnableMotion(false)
				end
				
				Trace.Entity.PositionSwitcher.FirstGhost = Table[1]
				Trace.Entity.PositionSwitcher.SecondGhost = Table[2]
				
				Trace.Entity:DeleteOnRemove(Table[1])
				Trace.Entity:DeleteOnRemove(Table[2])
			end
			
			self.Sel[1]:Remove()
			
			Trace.Entity.PositionSwitcher.ID = numpad.OnUp(self:GetOwner(), Key, "Position.Toggle", Trace.Entity, false)
			
			self:Message("Second entity has been selected, now press "..Key.." to switch between positions!")
			
			local function Function(Undo, Entity)
				if (Entity:IsValid()) then
					numpad.Remove(Entity.PositionSwitcher.ID)
					
					Entity:SetPos(Entity.PositionSwitcher.SecondPosition)
					Entity:SetAngles(Entity.PositionSwitcher.SecondAngle)
					
					Entity.PositionSwitcher = nil
				end
			end
			
			undo.Create("positionswitcher")
				undo.AddEntity(self.Sel[1])
				undo.AddEntity(self.Sel[2])
				
				if (Table[1] and Table[2]) then
					undo.AddEntity(Table[1])
					undo.AddEntity(Table[2])
				end
				
				undo.AddFunction(Function, Trace.Entity)
				
				undo.SetPlayer(self:GetOwner())
			undo.Finish()
			
			self.Sel[1] = nil
			self.Sel[2] = nil
		else
			self:Message("The first entity is no longer valid!")
			
			self.Sel[1] = nil
		end
	end
	
	return true
end

// Server

if SERVER then
	// Pressed key
	
	function TOOL.Pressed(Player, Entity, Key, IDX)
		if !Entity:IsValid() then return end
		
		if not Key then
			local Pos = {}
			
			Pos[1] = Entity.PositionSwitcher.FirstPosition
			Pos[2] = Entity.PositionSwitcher.SecondPosition
			
			local Ang = {}
			
			Ang[1] = Entity.PositionSwitcher.FirstAngle
			Ang[2] = Entity.PositionSwitcher.SecondAngle
			
			if (Entity.PositionSwitcher.FirstGhost) then
				Pos[1] = Entity.PositionSwitcher.FirstGhost:GetPos()
				Ang[1] = Entity.PositionSwitcher.FirstGhost:GetAngles()
			end
			
			if (Entity.PositionSwitcher.SecondGhost) then
				Pos[2] = Entity.PositionSwitcher.SecondGhost:GetPos()
				Ang[2] = Entity.PositionSwitcher.SecondGhost:GetAngles()
			end
			
			if (Entity.PositionSwitcher.Current == 1) then
				Entity:SetPos(Pos[2])
				Entity:SetAngles(Ang[2])
				
				Entity.PositionSwitcher.Current = 2
			else
				Entity:SetPos(Pos[1])
				Entity:SetAngles(Ang[1])
				
				Entity.PositionSwitcher.Current = 1
			end
			
			if (Wire_TriggerOutput) then
				Wire_TriggerOutput(Entity, "Position", Entity.PositionSwitcher.Current)
			end
			
			local Phys = Entity:GetPhysicsObject()
			
			if Phys then
				Phys:EnableMotion(false)
			end
		end
	end
	
	numpad.Register("Position.Toggle", TOOL.Pressed)
end

// Build CPanel

function TOOL.BuildCPanel(Panel)
	Panel:AddControl("Header", {Text = "#Tool_positionswitcher_name", Description	= "#Tool_positionswitcher_desc"})
	
	Panel:AddControl("Numpad", {Label = "Button", ButtonSize = "22", Command = "positionswitcher_Key"})
	
	Panel:AddControl("Checkbox", {Label = "#Show a ghost of the two positions", Command = "positionswitcher_Ghost"})
end